package jetbrains.buildServer.cuta.web;

import jetbrains.buildServer.cuta.logic.*;
import jetbrains.buildServer.cuta.logic.operators.ExternalContext;
import jetbrains.buildServer.cuta.logic.sheet.*;
import jetbrains.buildServer.serverSide.SBuildAgent;
import jetbrains.buildServer.web.openapi.*;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static jetbrains.buildServer.util.StringUtil.emptyIfNull;



public class AgentsCustomTableTabPage extends SimpleCustomTab
{

    @NotNull
    private final ExternalContext myExtContext;

    @NotNull
    private final CutaMainTab myMainTab;


    @NotNull
    private SubTabber mySubTabber;



    public AgentsCustomTableTabPage(final @NotNull WebControllerManager manager,
                                    final @NotNull ExternalContext extContext,
                                    final @NotNull String includeUrl,
                                    final @NotNull CutaMainTab mainTab,
                                    final @NotNull String placeAfterTabId)
    {
        super(manager,
              PlaceId.AGENTS_TAB,
              mainTab.getId(),
              includeUrl,
              mainTab.getName());
        myMainTab = mainTab;
        myExtContext = extContext;
        setPosition(PositionConstraint.after(placeAfterTabId));
        register();

        mySubTabber = new SubTabber();
        mySubTabber.setShowSubTabs(myMainTab.getSubTabCount() >= 2);
        mySubTabber.setMainTabId(mainTab.getId());
        mySubTabber.setSubTabs(myMainTab.getSubTabs());
    }


    @Override
    public void fillModel(@NotNull Map<String, Object> model,
                          @NotNull javax.servlet.http.HttpServletRequest request)
    {
        super.fillModel(model, request);

        Table table = new Table();

        List<SBuildAgent> agents = myExtContext.getBuildAgentManager().getRegisteredAgents(true);
        List<SBuildAgent> agents2 = myExtContext.getBuildAgentManager().getUnregisteredAgents();
        agents.addAll(agents2);

        PageDef pageDef = null;
        String requestedSubTabId = request.getParameter("subtab");
        if (requestedSubTabId != null)
            pageDef = myMainTab.getSubPageById(requestedSubTabId);
        if (pageDef == null)
            pageDef = myMainTab.getFirstPage();

        String sortBy = emptyIfNull(request.getParameter("sort-by"));
        String sortDirect = emptyIfNull(request.getParameter("sort-direct")).toUpperCase();

        fillSubTabs(pageDef);
        fillColumns(pageDef, table, sortBy, sortDirect);
        fillRows(pageDef, agents, table, sortBy, sortDirect);

        model.put("pgdef", pageDef);
        model.put("subtabber", mySubTabber);
        model.put("table", table);
    }


    private void fillSubTabs(PageDef pageDef)
    {
        mySubTabber.setCurrentTabId(pageDef.id);
    }


    private void fillColumns(PageDef pageDef, Table table, String sortBy, String sortDirect)
    {
        String onClickRefMainPart =
                "agents.html?tab=" + myMainTab.getId() + "&subtab=" + pageDef.id;

        for (ColumnDef columnDef: pageDef.columns)
        {
            Column column = new Column(table, columnDef.id, columnDef.caption);

            String resortDirect = columnDef.id.equalsIgnoreCase(sortBy) && sortDirect.equalsIgnoreCase("A") ? "D" : "A";
            String onClickRefSuffix = "sort-by=" + columnDef.id + "&sort-direct=" + resortDirect;
            column.setOnClickRef(onClickRefMainPart + '&' + onClickRefSuffix);

            if (columnDef.id.equalsIgnoreCase(sortBy))
            {
                column.setSortedAsc(sortDirect.equalsIgnoreCase("A"));
                column.setSortedDesc(sortDirect.equalsIgnoreCase("D"));
            }

            table.columns.add(column);
        }
    }


    private void fillRows(PageDef pageDef, Collection<SBuildAgent> agents, Table table, String sortBy, String sortDirect)
    {
        int columnsCount = pageDef.columns.size();

        for (SBuildAgent agent: agents)
        {
            Row row = new Row(table);

            for (ColumnDef columnDef: pageDef.columns)
            {
                Column column = table.getColumnByName(columnDef.id);
                if (column == null)
                    continue;

                Cell cell = new Cell(column, row);
                columnDef.content.run(agent, cell);
                row.cells.add(cell);
            }

            table.rows.add(row);
        }

        int sortingColumnNr = Integer.MIN_VALUE;
        if (sortBy != null && sortBy.length() > 0)
        {
            List<ColumnDef> theColumns = pageDef.columns;
            for (int i = 0; i < columnsCount; i++)
            {
                ColumnDef columnDef = theColumns.get(i);
                if (columnDef.id.equalsIgnoreCase(sortBy))
                    sortingColumnNr = i;
            }
        }

        if (sortingColumnNr >= 0)
        {
            int index2 = sortingColumnNr+1 < columnsCount ? sortingColumnNr+1 : Integer.MIN_VALUE;
            RowComparator rowComparator = new RowComparator(sortingColumnNr, index2, sortDirect.equalsIgnoreCase("D") ? -1 : +1);
            Collections.sort(table.rows, rowComparator);
        }

    }

}
